package com.song.admin.controller;

import com.song.admin.service.AdminUserService;
import com.song.api.BaseController;
import com.song.api.controller.admin.AdminMngControllerApi;
import com.song.api.controller.files.FileUploaderControllerApi;
import com.song.enums.FaceVerifyType;
import com.song.exception.GraceException;
import com.song.grace.result.GraceJSONResult;
import com.song.grace.result.ResponseStatusEnum;
import com.song.pojo.AdminUser;
import com.song.pojo.bo.AdminLoginBO;
import com.song.pojo.bo.NewAdminBO;
import com.song.utils.FaceVerifyUtils;
import com.song.utils.PagedGridResult;
import com.song.utils.RedisOperator;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;

@RestController
public class AdminMngController extends BaseController implements AdminMngControllerApi {

    @Autowired
    private AdminUserService adminUserService;

    @Autowired
    private RedisOperator redis;

    @Autowired
    private FaceVerifyUtils faceVerifyUtils;


    @Override
    public GraceJSONResult adminLogin(AdminLoginBO adminLoginBO,
                                      HttpServletRequest request,
                                      HttpServletResponse response) {

        // 0. 验证BO中的用户名信息
        if (StringUtils.isBlank(adminLoginBO.getUsername())) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.ADMIN_USERNAME_NULL_ERROR);
        }
        if (StringUtils.isBlank(adminLoginBO.getPassword())) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.ADMIN_PASSWORD_NULL_ERROR);
        }

        // 1.查询admin用户的信息
        AdminUser admin = adminUserService.queryAdminByUsername(adminLoginBO.getUsername());

        // 2.判断admin不能为空，如果为空则登录失败
        if (admin == null) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.ADMIN_NOT_EXIT_ERROR);
        }

        // 3.判断密码是否匹配
        boolean isPwdMatch = BCrypt.checkpw(adminLoginBO.getPassword(), admin.getPassword());
        if (isPwdMatch) {
            doLoginSettings(admin, request, response);
            return GraceJSONResult.ok();
        } else {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.ADMIN_NOT_EXIT_ERROR);
        }
    }

    @Override
    public GraceJSONResult adminIsExist(String username) {
        checkAdminExist(username);
        return GraceJSONResult.ok();
    }

    @Transactional
    @Override
    public GraceJSONResult addNewAdmin(NewAdminBO newAdminBO,
                                       HttpServletRequest request,
                                       HttpServletResponse response) {

        // 1.base64不为空，则代表人脸入库，否则需要用户输入密码和确认密码
        if (StringUtils.isNotBlank(newAdminBO.getImg64())) {
        }

        // 2.密码不能为空，则需判断两次输入一致
        if (StringUtils.isNotBlank(newAdminBO.getPassword())) {
            if (!newAdminBO.getPassword().equalsIgnoreCase(newAdminBO.getConfirmPassword())) {
                GraceException.display(ResponseStatusEnum.ADMIN_CONFIRMPASSWORD_ERROR);
            }
        }

        // 3.验证用户名唯一
        checkAdminExist(newAdminBO.getUsername());

        // 4.新增管理员
        adminUserService.CreateAdminUser(newAdminBO);

        return GraceJSONResult.ok();
    }

    @Override
    public GraceJSONResult getAdminList(Integer page, Integer pageSize) {
        if (page == null) {
            page = COMMON_START_PAGE;
        }
        if (pageSize == null) {
            pageSize = COMMON_PAGE_SIZE;
        }
        PagedGridResult result = adminUserService.queryAdminList(page, pageSize);

        return GraceJSONResult.ok(result);
    }

    @Override
    public GraceJSONResult adminLoguot(String adminId,
                                       HttpServletRequest request,
                                       HttpServletResponse response) {

        // 1. 清除用户已登录的会话信息
        redis.del(REDIS_ADMIN_TOKEN + adminId);

        // 2. 清除用户admin在cookie登录的相关信息
        deleteCookie(request, response, "atoken");
        deleteCookie(request, response, "aname");
        deleteCookie(request, response, "aid");
        return GraceJSONResult.ok();
    }

    @Autowired
    private FileUploaderControllerApi fileUploaderControllerApi;

    @Override
    public GraceJSONResult adminFaceLogin(AdminLoginBO adminLoginBO,
                                          HttpServletRequest request,
                                          HttpServletResponse response) {

        // 0.判断用户和人脸信息不能为空
        if (StringUtils.isBlank(adminLoginBO.getUsername())) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.ADMIN_USERNAME_NULL_ERROR);
        }
        String tempFace64 = adminLoginBO.getImg64();
        if (StringUtils.isBlank(tempFace64)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.ADMIN_FACE_NULL_ERROR);
        }

        // 1.从数据库查询出faceId
        AdminUser admin = adminUserService.queryAdminByUsername(adminLoginBO.getUsername());
        String faceId = admin.getFaceId();

        if (StringUtils.isBlank(faceId)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.ADMIN_FACE_LOGIN_ERROR);
        }

        // 2.请求文件服务，获取人脸数据的base64数据
//        String fileServerUrlExecute = "http://"
//                + MyServiceList.SERVICE_FILES
//                +"/fs/readFace64InGridFS?faceId="
//                + faceId;
//        ResponseEntity<GraceJSONResult> responseEntity = restTemplate.getForEntity(fileServerUrlExecute, GraceJSONResult.class);
//        GraceJSONResult responseBody = responseEntity.getBody();
        // 发起远程调用，获得人脸数据的base64数据
        GraceJSONResult responseBody = fileUploaderControllerApi.readFace64InGridFS(faceId);

        String base64DB = (String) responseBody.getData();

        // 3.调用腾讯云人脸对比识别，判断可信度，从而实现人脸登录
        boolean result = faceVerifyUtils.faceVerify(FaceVerifyType.BASE64.type, tempFace64, base64DB, 60);

        if (!result) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.ADMIN_FACE_LOGIN_ERROR);
        }

        // 4.admin登录后的数据设置，redis与cookie
        doLoginSettings(admin, request, response);

        return GraceJSONResult.ok();
    }

    /**
     * 检测管理员存在
     *
     * @param username
     */
    public void checkAdminExist(String username) {
        AdminUser admin = adminUserService.queryAdminByUsername(username);

        if (admin != null) {
            GraceException.display(ResponseStatusEnum.ADMIN_USERNAME_EXIST_ERROR);
        }
    }

    /**
     * 用于admin用户登录过后的基本信息设置
     *
     * @param admin
     * @param request
     * @param response
     */
    private void doLoginSettings(AdminUser admin,
                                 HttpServletRequest request,
                                 HttpServletResponse response) {
        // 保存token放入到redis中
        String token = UUID.randomUUID().toString();
        redis.set(REDIS_ADMIN_TOKEN + admin.getId(), token);

        // 保存admin登录基本token信息到cookie中
        setCookie(request, response, "atoken", token, COOKIE_MONTH);
        setCookie(request, response, "aid", admin.getId(), COOKIE_MONTH);
        setCookie(request, response, "aname", admin.getAdminName(), COOKIE_MONTH);
    }

}